package com.szh.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.szh.common.utils.HttpUtils;
import com.szh.gulimall.member.dao.MemberLevelDao;
import com.szh.gulimall.member.entity.MemberLevelEntity;
import com.szh.gulimall.member.exception.MobileExistException;
import com.szh.gulimall.member.exception.UsernameExistException;
import com.szh.gulimall.member.vo.MemberLoginVo;
import com.szh.gulimall.member.vo.MemberRegisterVo;
import com.szh.gulimall.member.vo.SocialUser;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.szh.common.utils.PageUtils;
import com.szh.common.utils.Query;

import com.szh.gulimall.member.dao.MemberDao;
import com.szh.gulimall.member.entity.MemberEntity;
import com.szh.gulimall.member.service.MemberService;

@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MemberServiceImpl.class);

    @Autowired
    private MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<>()
        );
        return new PageUtils(page);
    }

    /**
     * 注册
     */
    @Override
    public void register(MemberRegisterVo memberRegisterVo) {
        MemberEntity memberEntity = new MemberEntity();
        //设置会员默认等级
        MemberLevelEntity memberLevelEntity = memberLevelDao.getDefaultLevel();
        memberEntity.setLevelId(memberLevelEntity.getId());
        //检查用户名和手机号是否唯一，如果已存在则无法注册，同时throws抛出异常
        checkMobileUnique(memberRegisterVo.getMobile());
        checkUsernameUnique(memberRegisterVo.getUserName());
        //用户名和手机号都唯一，再将信息进行set
        memberEntity.setMobile(memberRegisterVo.getMobile());
        memberEntity.setUsername(memberRegisterVo.getUserName());
        //设置密码，将密码加密存入数据库
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode(memberRegisterVo.getPassword());
        memberEntity.setPassword(password);
        memberEntity.setNickname(memberRegisterVo.getUserName()); //昵称
        memberEntity.setEmail(memberRegisterVo.getMobile() + "@qq.com"); //邮箱
        memberEntity.setIntegration(10); //积分
        memberEntity.setGrowth(10); //成长值
        memberEntity.setStatus(0); //启用状态，0启用，1禁用
        memberEntity.setCreateTime(new Date()); //注册时间
        //将用户信息保存到数据库
        baseMapper.insert(memberEntity);
    }

    /**
     * 检查手机号是否唯一
     */
    @Override
    public void checkMobileUnique(String mobile) {
        QueryWrapper<MemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", mobile);
        Integer count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new MobileExistException();
        }
    }

    /**
     * 检查用户名是否唯一
     */
    @Override
    public void checkUsernameUnique(String username) {
        QueryWrapper<MemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        Integer count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new UsernameExistException();
        }
    }

    /**
     * 登录
     */
    @Override
    public MemberEntity login(MemberLoginVo memberLoginVo) {
        String loginAccount = memberLoginVo.getLoginAccount();
        String password = memberLoginVo.getPassword();
        QueryWrapper<MemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", loginAccount).or()
                .eq("mobile", loginAccount).or()
                .eq("email", loginAccount);
        //在数据库中查询将要登录的用户信息是否存在
        MemberEntity memberEntity = baseMapper.selectOne(queryWrapper);
        if (Objects.isNull(memberEntity)) { //不存在，直接返回null
            return null;
        } else { //存在则进行密码匹配
            String encodePassword = memberEntity.getPassword();
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            boolean flag = passwordEncoder.matches(password, encodePassword);
            if (flag) {
                return memberEntity;
            } else {
                return null;
            }
        }
    }

    /**
     * Gitee登录或注册，登录过执行更新相关属性操作，未登录过则执行注册操作
     */
    @Override
    public MemberEntity oauthLogin(SocialUser socialUser) throws Exception {
        String accessToken = socialUser.getAccess_token();
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("access_token", accessToken);
        //根据access_token获取Gitee授权该用户的资料
        HttpResponse response = HttpUtils.doGet("https://gitee.com", "/api/v5/user", "get",
                new HashMap<>(), paramMap);
        if (response.getStatusLine().getStatusCode() == 200) {
            //将响应体数据转为json字符串
            String json = EntityUtils.toString(response.getEntity());
            //将json字符串转为JSONObject对象，类似于Map
            JSONObject jsonObject = JSON.parseObject(json);
            String giteeId = jsonObject.getString("id");
            //判断当前用户是否已经注册过
            QueryWrapper<MemberEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("gitee_id", giteeId);
            MemberEntity memberEntity = baseMapper.selectOne(queryWrapper);
            if (Objects.nonNull(memberEntity)) { //当前用户注册过，更新ums_member表的access_token、expires_in
                MemberEntity entity = new MemberEntity();
                entity.setId(memberEntity.getId());
                entity.setGiteeId(giteeId);
                entity.setAccessToken(socialUser.getAccess_token());
                entity.setExpiresIn(socialUser.getExpires_in());
                baseMapper.updateById(entity);
                memberEntity.setGiteeId(giteeId);
                memberEntity.setAccessToken(socialUser.getAccess_token());
                memberEntity.setExpiresIn(socialUser.getExpires_in());
                return memberEntity;
            } else { //当前用户未注册，执行注册操作，将数据插入ums_member表中
                MemberEntity entity = new MemberEntity();
                entity.setUsername(jsonObject.getString("login"));
                entity.setNickname(jsonObject.getString("name"));
                entity.setSign(jsonObject.getString("blog"));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                String dateStr = jsonObject.getString("created_at");
                entity.setCreateTime(sdf.parse(dateStr));
                entity.setGiteeId(giteeId);
                entity.setAccessToken(socialUser.getAccess_token());
                entity.setExpiresIn(socialUser.getExpires_in());
                baseMapper.insert(entity);
                return entity;
            }
        } else {
            return null;
        }
    }
}